Spring Boot JPA অ্যাপ্লিকেশন টেস্টিং একটি গুরুত্বপূর্ণ অংশ, যা ডাটাবেস সম্পর্কিত কোডের সঠিকতা এবং কার্যকারিতা নিশ্চিত করতে সাহায্য করে। Spring Boot JPA অ্যাপ্লিকেশন টেস্টিং করতে হলে, আমরা সাধারণত JUnit এবং Spring Test ফ্রেমওয়ার্ক ব্যবহার করি। Spring Boot JPA অ্যাপ্লিকেশনকে টেস্ট করার জন্য, @DataJpaTest এবং @SpringBootTest অ্যানোটেশন ব্যবহার করে ইউনিট টেস্ট এবং ইন্টিগ্রেশন টেস্ট করা যায়।
এখানে আমরা Spring Boot JPA অ্যাপ্লিকেশন টেস্ট করার বিভিন্ন পদ্ধতি নিয়ে আলোচনা করব, যেমন JUnit, @DataJpaTest, @SpringBootTest, এবং ইন-মেমরি ডাটাবেস ব্যবহার করে টেস্টিং করা।
Step 1: Dependencies for Testing
Spring Boot JPA অ্যাপ্লিকেশন টেস্ট করতে কিছু বিশেষ ডিপেনডেন্সি প্রয়োজন হয়, যেমন spring-boot-starter-test। এটি JUnit, Mockito, Hamcrest ইত্যাদি টুলস অন্তর্ভুক্ত করে, যা টেস্টিং সহজ করে তোলে।
Maven (pom.xml):
<dependencies>
<!-- Spring Boot Test Dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- H2 Database (For In-Memory Testing) -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
Gradle (build.gradle):
dependencies {
// Spring Boot Starter Test
testImplementation 'org.springframework.boot:spring-boot-starter-test'
// H2 Database for in-memory testing
runtimeOnly 'com.h2database:h2'
}
Step 2: JUnit Test Using @DataJpaTest
@DataJpaTest অ্যানোটেশন Spring Boot এর বিশেষ টেস্টিং অ্যানোটেশন, যা শুধুমাত্র JPA সম্পর্কিত কম্পোনেন্টস যেমন Repository টেস্ট করতে ব্যবহৃত হয়। এটি ডাটাবেস টেস্টিংয়ের জন্য ইন-মেমরি ডাটাবেস ব্যবহার করে, যা টেস্টিং প্রক্রিয়াকে দ্রুত এবং সহজ করে তোলে।
Example: Testing Repository with @DataJpaTest
ধরা যাক, আমাদের একটি Employee Entity এবং Repository রয়েছে।
Employee Entity:
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String department;
// Getters and Setters
}
Employee Repository:
@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
List<Employee> findByDepartment(String department);
}
Employee Repository Test:
@DataJpaTest
public class EmployeeRepositoryTest {
@Autowired
private EmployeeRepository employeeRepository;
@Test
public void testSaveAndFindEmployee() {
// Create a new Employee
Employee employee = new Employee();
employee.setName("John Doe");
employee.setDepartment("IT");
// Save the employee
Employee savedEmployee = employeeRepository.save(employee);
// Assert the employee is saved and found
assertNotNull(savedEmployee.getId());
assertEquals("John Doe", savedEmployee.getName());
// Test finding by department
List<Employee> itEmployees = employeeRepository.findByDepartment("IT");
assertEquals(1, itEmployees.size());
assertEquals("John Doe", itEmployees.get(0).getName());
}
}
এখানে, @DataJpaTest ব্যবহার করে EmployeeRepository টেস্ট করা হয়েছে। findByDepartment() মেথডটি টেস্ট করে ডাটাবেস থেকে IT বিভাগের কর্মচারী খুঁজে পাওয়া যাচ্ছে কিনা তা নিশ্চিত করা হয়েছে।
@DataJpaTestকেবল JPA রিলেটেড টেস্টিং করে, যেখানে ডাটাবেসের নির্দিষ্ট রেপোজিটরি টেস্ট করা হয়।- In-memory Database: ডিফল্টভাবে H2 ইন-মেমরি ডাটাবেস ব্যবহৃত হয়, তবে আপনি ডাটাবেস কনফিগারেশন পরিবর্তন করে আপনার পছন্দমত ডাটাবেস ব্যবহার করতে পারেন।
Step 3: Testing with @SpringBootTest
@SpringBootTest অ্যানোটেশন একটি পূর্ণ Spring Context লোড করে, যা অ্যাপ্লিকেশনের সমস্ত কম্পোনেন্ট (Controllers, Services, Repositories ইত্যাদি) টেস্ট করতে ব্যবহৃত হয়। এটি ইন্টিগ্রেশন টেস্টিংয়ের জন্য উপযোগী, যেখানে সম্পূর্ণ অ্যাপ্লিকেশন লোড হয় এবং বিভিন্ন কম্পোনেন্টের মধ্যে ইন্টারঅ্যাকশন টেস্ট করা হয়।
Example: Full Application Test with @SpringBootTest
@SpringBootTest
public class EmployeeServiceTest {
@Autowired
private EmployeeService employeeService;
@Autowired
private EmployeeRepository employeeRepository;
@Test
public void testEmployeeService() {
// Create a new Employee
Employee employee = new Employee();
employee.setName("Jane Doe");
employee.setDepartment("HR");
// Save the employee using service
Employee savedEmployee = employeeService.saveEmployee(employee);
// Assert the employee is saved
assertNotNull(savedEmployee.getId());
assertEquals("Jane Doe", savedEmployee.getName());
// Test if employee is available in repository
Employee foundEmployee = employeeRepository.findById(savedEmployee.getId()).orElse(null);
assertNotNull(foundEmployee);
assertEquals("HR", foundEmployee.getDepartment());
}
}
এখানে, @SpringBootTest ব্যবহার করে EmployeeService এবং EmployeeRepository টেস্ট করা হয়েছে। employeeService.saveEmployee() মেথডটি ব্যবহার করে কর্মচারী সেভ করা হয়েছে এবং তারপর ডাটাবেস থেকে সেই কর্মচারী খুঁজে বের করা হয়েছে।
@SpringBootTest পূর্ণ Spring Context লোড করে, এবং এটি সব ধরনের টেস্টিং (উদাহরণস্বরূপ, Web, Service, Repository ইত্যাদি) করতে সহায়তা করে।
Step 4: In-memory Database (H2 Database) ব্যবহার
Spring Boot JPA টেস্ট করার জন্য H2 ডাটাবেস সাধারণত ইন-মেমরি ডাটাবেস হিসেবে ব্যবহৃত হয়, যা টেস্টিং করার জন্য খুব উপযোগী। H2 ডাটাবেসটি Spring Boot অ্যাপ্লিকেশনে application.properties ফাইলে কনফিগার করা হয়।
H2 Database কনফিগারেশন (application.properties):
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=update
spring.h2.console.enabled=true
এখানে, H2 ডাটাবেস ইন-মেমরি ব্যবহৃত হচ্ছে, এবং spring.jpa.hibernate.ddl-auto=update ব্যবহার করা হচ্ছে যা Hibernate কে ডাটাবেস স্কিমা আপডেট করতে নির্দেশ দেয়।
Step 5: Mocking Repositories using Mockito
Spring Boot অ্যাপ্লিকেশন টেস্ট করার সময়, বিশেষ করে Service Layer টেস্ট করতে হলে আপনি Mockito ব্যবহার করতে পারেন, যাতে রেপোজিটরি এবং অন্যান্য ডিপেনডেন্সি মক করা যায়।
Example: Mocking Repository in Service Layer Test
@SpringBootTest
public class EmployeeServiceTest {
@MockBean
private EmployeeRepository employeeRepository;
@Autowired
private EmployeeService employeeService;
@Test
public void testSaveEmployee() {
Employee employee = new Employee();
employee.setName("Alice");
employee.setDepartment("Finance");
Mockito.when(employeeRepository.save(Mockito.any(Employee.class))).thenReturn(employee);
Employee savedEmployee = employeeService.saveEmployee(employee);
assertEquals("Alice", savedEmployee.getName());
assertEquals("Finance", savedEmployee.getDepartment());
}
}
এখানে, @MockBean ব্যবহার করে EmployeeRepository মক করা হয়েছে, এবং Mockito এর মাধ্যমে save() মেথডের আচরণ নির্ধারণ করা হয়েছে।
সারাংশ
- Spring Boot JPA Testing: Spring Boot JPA অ্যাপ্লিকেশন টেস্ট করতে JUnit, Spring Test, এবং Mockito ব্যবহার করা হয়।
- @DataJpaTest: শুধুমাত্র JPA এর Repository এবং ডেটাবেস অপারেশন টেস্ট করার জন্য ব্যবহৃত হয়।
- @SpringBootTest: পূর্ণ Spring Context লোড করে এবং এটি ইন্টিগ্রেশন টেস্টিংয়ে ব্যবহার হয়, যেখানে সব কম্পোনেন্ট টেস্ট করা হয়।
- H2 Database: ইন-মেমরি ডাটাবেস হিসেবে H2 ব্যবহৃত হয়, যা দ্রুত এবং সহজ ডাটাবেস টেস্টিংয়ে সাহায্য করে।
এই সমস্ত টেস্টিং টুলস এবং কৌশলগুলি Spring Boot JPA অ্যাপ্লিকেশন ডেভেলপমেন্টে অত্যন্ত কার্যকর এবং পারফরম্যান্স নিশ্চিত করতে সাহায্য করে।
Spring Boot JPA অ্যাপ্লিকেশনগুলির জন্য Unit Testing এবং Integration Testing অত্যন্ত গুরুত্বপূর্ণ, কারণ এই পরীক্ষাগুলি আপনার ডেটাবেস এবং অ্যাপ্লিকেশনের লজিক্যাল অংশগুলির কার্যকারিতা নিশ্চিত করে। JUnit এবং Spring Test ফ্রেমওয়ার্কের মাধ্যমে স্প্রিং বুট জেপিএ অ্যাপ্লিকেশনে Unit Testing এবং Integration Testing করা হয়।
এখানে আমরা দেখব কিভাবে Spring Boot JPA অ্যাপ্লিকেশনে Unit Testing এবং Integration Testing করা যায়।
Step 1: Maven ডিপেনডেন্সি যোগ করা
Unit এবং Integration Testing করার জন্য প্রয়োজনীয় ডিপেনডেন্সি আপনার pom.xml ফাইলে যোগ করুন।
<dependencies>
<!-- Spring Boot Starter Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- Spring Boot Starter Test (For Unit and Integration Testing) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- H2 Database (In-memory Database for Testing) -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
এখানে, spring-boot-starter-test ডিপেনডেন্সিটি JUnit, Mockito, Spring Test, Hamcrest ইত্যাদি টেস্টিং লাইব্রেরি অন্তর্ভুক্ত করে, যা Unit এবং Integration Testing-এর জন্য ব্যবহৃত হবে। এছাড়া, h2 ডাটাবেস ইন-মেমরি ডাটাবেস হিসেবে ব্যবহার করা হচ্ছে, যাতে টেস্টিংয়ের সময় একটি ডেডিকেটেড ডাটাবেস তৈরি না করতে হয়।
Step 2: Unit Testing
Unit Testing সাধারণত সিঙ্গল ক্লাসের উপর পরীক্ষা করা হয় এবং বাহ্যিক ডিপেনডেন্সির উপর নির্ভরশীলতা কমাতে Mockito ব্যবহৃত হয়। এখানে আমরা ProductService এর একটি সিম্পল ইউনিট টেস্ট তৈরি করব।
Service Class:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
public Product saveProduct(Product product) {
return productRepository.save(product);
}
public Product getProductById(Long id) {
return productRepository.findById(id).orElse(null);
}
}
ProductService Unit Test:
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
public class ProductServiceTest {
@Mock
private ProductRepository productRepository;
@InjectMocks
private ProductService productService;
private Product product;
@BeforeEach
public void setUp() {
product = new Product(1L, "Test Product", 100.0);
}
@Test
public void testSaveProduct() {
when(productRepository.save(product)).thenReturn(product);
Product savedProduct = productService.saveProduct(product);
assertNotNull(savedProduct);
assertEquals("Test Product", savedProduct.getName());
}
@Test
public void testGetProductById() {
when(productRepository.findById(1L)).thenReturn(Optional.of(product));
Product foundProduct = productService.getProductById(1L);
assertNotNull(foundProduct);
assertEquals("Test Product", foundProduct.getName());
}
}
এখানে, Mockito ব্যবহার করে ProductRepository এর মক তৈরি করা হয়েছে এবং ProductService ক্লাসের মেথডগুলির টেস্ট করা হয়েছে।
Step 3: Integration Testing
Integration Testing এর মাধ্যমে আমরা একটি সম্পূর্ণ অ্যাপ্লিকেশন স্তরের পরীক্ষা করি, যেখানে ডাটাবেসসহ অন্যান্য কম্পোনেন্টগুলি একত্রে কাজ করে। স্প্রিং বুটে @SpringBootTest অ্যানোটেশন ব্যবহার করে আমরা সহজেই Integration Test করতে পারি।
Integration Test for ProductService:
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.ANY)
public class ProductServiceIntegrationTest {
@Autowired
private ProductService productService;
@Autowired
private ProductRepository productRepository;
@Test
public void testSaveProduct() {
Product product = new Product(1L, "Integration Test Product", 150.0);
Product savedProduct = productService.saveProduct(product);
assertNotNull(savedProduct);
assertEquals("Integration Test Product", savedProduct.getName());
}
@Test
public void testGetProductById() {
Product product = new Product(1L, "Integration Test Product", 150.0);
productService.saveProduct(product);
Product foundProduct = productService.getProductById(1L);
assertNotNull(foundProduct);
assertEquals("Integration Test Product", foundProduct.getName());
}
}
এখানে, @SpringBootTest অ্যানোটেশন ব্যবহার করা হয়েছে যাতে পুরো অ্যাপ্লিকেশন কনটেক্সট লোড হয় এবং এক্সটেন্ডেড টেস্ট করা যায়। @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.ANY) দিয়ে আমরা একটি ইন-মেমরি ডাটাবেস ব্যবহার করছি, যাতে টেস্টের সময় ডাটাবেসের কোনো রিয়েল কনফিগারেশন প্রয়োজন না হয়।
Step 4: Test Configuration
টেস্ট করার সময় @SpringBootTest এর সাথে ডাটাবেসের কনফিগারেশন নির্দিষ্ট করা হলে, ইন-মেমরি ডাটাবেস বা অন্যান্য ডাটাবেস কনফিগারেশন কার্যকর করা যেতে পারে। এখানে H2 Database ব্যবহার করা হচ্ছে।
# application-test.properties (For Integration Tests)
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=create-drop
এখানে, spring.jpa.hibernate.ddl-auto=create-drop ব্যবহার করলে টেস্টের শুরুতে ডাটাবেস স্কিমা তৈরি হবে এবং টেস্টের শেষে তা মুছে ফেলা হবে।
Step 5: Running Tests
স্প্রিং বুট অ্যাপ্লিকেশনে টেস্ট রান করার জন্য, আপনি নিচের কমান্ড ব্যবহার করতে পারেন:
Maven:
mvn test
Gradle:
gradle test
সারাংশ
স্প্রিং বুট জেপিএ (Spring Boot JPA) অ্যাপ্লিকেশনে Unit Testing এবং Integration Testing গুরুত্বপূর্ণ ভূমিকা পালন করে, বিশেষ করে যখন আপনার ডেটাবেসের সাথে কাজ করার জন্য CRUD অপারেশনগুলো যাচাই করতে হয়। JUnit, Mockito, এবং Spring Test ব্যবহার করে স্প্রিং বুট অ্যাপ্লিকেশনগুলির কার্যকারিতা পরীক্ষা করা হয়।
- Unit Testing: একক কম্পোনেন্টের (যেমন,
ServiceবাRepository) পরীক্ষা করা হয়, যেখানে বাইরের ডিপেনডেন্সি মক করা হয়। - Integration Testing: পুরো অ্যাপ্লিকেশন কনটেক্সট লোড করে বাস্তব ডেটাবেসের সাথে পরীক্ষা করা হয়, যেখানে ডাটাবেস অপারেশনসহ অন্যান্য সিস্টেমের সঙ্গে একত্রে পরীক্ষা করা হয়।
এই টেস্টিং কৌশলগুলি আপনার স্প্রিং বুট জেপিএ অ্যাপ্লিকেশনকে আরও নির্ভরযোগ্য এবং উন্নত করে তোলে।
Spring Boot JPA এবং In-Memory Testing
Spring Boot JPA তে in-memory database testing এর মাধ্যমে আমরা সহজেই unit tests বা integration tests তৈরি করতে পারি। H2 Database একটি জনপ্রিয় ইন-মেমরি ডেটাবেস যা testing উদ্দেশ্যে ব্যবহার করা হয়। H2 ডেটাবেস সম্পূর্ণরূপে in-memory থাকে, অর্থাৎ ডেটাবেসের সমস্ত ডেটা শুধুমাত্র রানটাইমে থাকে এবং অ্যাপ্লিকেশন বন্ধ হলে ডেটা হারিয়ে যায়।
Spring Boot এবং JPA এর সাথে H2 database ব্যবহার করে in-memory testing করা অত্যন্ত সহজ এবং কার্যকর। এখানে, আমরা দেখব কিভাবে Spring Boot JPA প্রজেক্টে H2 Database ব্যবহার করে ইন-মেমরি টেস্টিং করা যায়।
1. Spring Boot প্রজেক্ট সেটআপ
1.1. Dependency Setup
প্রথমে H2 Database এবং Spring Boot Test এর জন্য ডিপেনডেন্সি আপনার pom.xml ফাইলে যোগ করতে হবে।
<dependencies>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Starter Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- H2 Database for In-Memory Testing -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Spring Boot Starter Test for Unit Testing -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
1.2. application.properties কনফিগারেশন
H2 Database এবং JPA configuration সেটআপ করার জন্য application.properties ফাইলে কিছু কনফিগারেশন লিখতে হবে।
# H2 Database Configuration
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=create
spring.jpa.show-sql=true
spring.h2.console.enabled=true
এখানে, H2 ডেটাবেসের ইন-মেমরি মোডে ব্যবহার করার জন্য কনফিগারেশন করা হয়েছে। DB_CLOSE_DELAY=-1 সেট করার মাধ্যমে ডেটাবেস বন্ধ হওয়ার পরেও ডেটা রাখা হয়।
2. JPA Entity তৈরি করা
2.1. User Entity তৈরি করা
এখানে একটি User Entity তৈরি করা হয়েছে, যা H2 ডেটাবেসের সাথে ইন্টিগ্রেট করা হবে।
package com.example.model;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class User {
@Id
private Long id;
private String name;
private String email;
// Getters and Setters
}
2.2. UserRepository Interface তৈরি করা
Spring Data JPA তে JpaRepository ইন্টারফেস ব্যবহার করে আমরা CRUD অপারেশন গুলি পরিচালনা করবো।
package com.example.repository;
import com.example.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
// Custom queries can go here if needed
}
3. Unit Test বা Integration Test তৈরি করা
Spring Boot এবং JPA এর জন্য in-memory testing করার জন্য আমরা Spring Boot Test ব্যবহার করবো। @DataJpaTest অ্যানোটেশন ব্যবহার করে, JPA সম্পর্কিত সমস্ত কনফিগারেশন এবং ডেটাবেস সংক্রান্ত কাজ শুধুমাত্র টেস্ট কেসের জন্য চালানো যাবে।
3.1. Test Class তৈরি করা
UserRepository এর জন্য একটি টেস্ট ক্লাস তৈরি করা হচ্ছে, যেখানে H2 Database তে ইন-মেমরি ডেটাবেস ব্যবহার করা হবে।
package com.example;
import com.example.model.User;
import com.example.repository.UserRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.junit.jupiter.api.Assertions.*;
@DataJpaTest
public class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
public void testSaveUser() {
User user = new User();
user.setId(1L);
user.setName("John Doe");
user.setEmail("john.doe@example.com");
User savedUser = userRepository.save(user);
assertNotNull(savedUser);
assertEquals(user.getName(), savedUser.getName());
}
@Test
public void testFindUserByEmail() {
User user = new User();
user.setId(2L);
user.setName("Jane Doe");
user.setEmail("jane.doe@example.com");
userRepository.save(user);
User foundUser = userRepository.findById(2L).orElse(null);
assertNotNull(foundUser);
assertEquals("jane.doe@example.com", foundUser.getEmail());
}
}
3.2. Test Execution
@DataJpaTest: এই অ্যানোটেশনটি শুধুমাত্র JPA সম্পর্কিত টেস্টিংয়ের জন্য ব্যবহৃত হয়। এটি in-memory database কে টেস্ট চলাকালীন স্বয়ংক্রিয়ভাবে প্রস্তুত করে এবং টেস্ট শেষ হওয়ার পর তা মুছে ফেলে।- Test Methods:
testSaveUser: এখানে,Userঅবজেক্ট ডাটাবেসে সেভ করা হচ্ছে এবং এটি সঠিকভাবে সেভ হয়েছে কিনা চেক করা হচ্ছে।testFindUserByEmail: এখানে, ডেটাবেসে সেভ করা ইউজারটি আবার খোঁজা হচ্ছে এবং নিশ্চিত করা হচ্ছে যে এটি সঠিকভাবে সেভ হয়েছে।
3.3. Test Run
এই টেস্ট ক্লাসটি চালানোর পরে, আপনার UserRepository এর ডেটাবেস অপারেশন পরীক্ষা করা যাবে এবং H2 ইন-মেমরি ডেটাবেস ব্যবহার করা হবে। JUnit এর মাধ্যমে টেস্ট সফলভাবে সম্পন্ন হলে, এটি নিশ্চিত করবে যে আপনার JPA সম্পর্কিত কাজ সঠিকভাবে কাজ করছে।
4. Test Logs
টেস্ট চলাকালীন, আপনি H2 console এর মাধ্যমে আপনার ইন-মেমরি ডেটাবেসটি দেখতে পারেন।
- H2 Console Access:
http://localhost:8080/h2-console/ - Console Configuration:
- JDBC URL:
jdbc:h2:mem:testdb - Username:
sa - Password:
password
- JDBC URL:
এখানে আপনি H2 কনসোল ব্যবহার করে ইন-মেমরি ডেটাবেসের ডেটা দেখতে পারেন।
সারাংশ
Spring Boot JPA তে H2 Database ব্যবহার করে in-memory testing খুবই সহজ এবং কার্যকরী। @DataJpaTest অ্যানোটেশন ব্যবহার করে, আপনি JPA সম্পর্কিত unit tests বা integration tests তৈরি করতে পারেন যেখানে H2 Database ইন-মেমরি মোডে কাজ করে। এতে ডেটাবেস অপারেশনগুলি দ্রুত পরীক্ষা করা যায় এবং প্রোডাকশনের ডেটাবেসের উপর কোনো প্রভাব না পড়ে। H2 Database এবং Spring Boot JPA এর সমন্বয়ে এই ধরনের টেস্টিং আপনার অ্যাপ্লিকেশনের ডেটাবেস সম্পর্কিত লজিক যাচাই করতে সহায়ক হবে।
@DataJpaTest এবং @MockBean এর ভূমিকা
Spring Boot Testing স্প্রিং বুট অ্যাপ্লিকেশনগুলির টেস্টিং সহজ এবং কার্যকরী করতে সহায়তা করে। @DataJpaTest এবং @MockBean দুটি গুরুত্বপূর্ণ অ্যানোটেশন যা স্প্রিং বুট জেপিএ (Spring Boot JPA)-তে টেস্টিং ব্যবহৃত হয়।
- @DataJpaTest: এটি শুধুমাত্র ডেটাবেস লেয়ারের (JPA) টেস্টিং জন্য ব্যবহৃত হয়। এটি শুধুমাত্র
@Entityক্লাস,JpaRepositoryএবং ডেটাবেস সম্পর্কিত অপারেশনগুলির টেস্টিং করে এবং স্বয়ংক্রিয়ভাবে একটি ইন-মেমরি ডেটাবেস (যেমন H2) ব্যবহার করে। - @MockBean: এটি স্প্রিং বুটের জন্য একটি অ্যানোটেশন যা স্প্রিং কনটেইনারে মক (mock) Bean তৈরি করতে ব্যবহৃত হয়। এটি সাধারণত সার্ভিস বা অন্যান্য বিহেভিয়ার যেগুলির জন্য প্রকৃত ইনস্ট্যান্সের প্রয়োজন হয় না, সেগুলির টেস্ট করার জন্য ব্যবহৃত হয়।
এই দুটি অ্যানোটেশন ব্যবহার করে, আপনি JPA রেপোজিটরির জন্য টেস্ট করতে পারেন এবং মক বিহেভিয়ার দিয়ে সার্ভিসের টেস্টিং করতে পারেন।
@DataJpaTest এর মাধ্যমে JPA Testing
@DataJpaTest অ্যানোটেশন ব্যবহার করে আপনি সহজে ডেটাবেস অপারেশন, যেমন find, save, delete, ইত্যাদি টেস্ট করতে পারেন। এটি JpaRepository ইন্টারফেসের মাধ্যমে ডেটাবেসের রিড ও রাইট অপারেশন পরীক্ষা করতে সাহায্য করে।
উদাহরণ: @DataJpaTest ব্যবহার করে টেস্টিং
ধরা যাক, আমাদের একটি User Entity ক্লাস রয়েছে এবং একটি UserRepository ইন্টারফেস তৈরি করা আছে।
Step 1: User Entity ক্লাস তৈরি করা
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
// Constructor, Getters, and Setters
public User(String name, String email) {
this.name = name;
this.email = email;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
Step 2: UserRepository তৈরি করা
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
User findByEmail(String email);
}
Step 3: @DataJpaTest এর মাধ্যমে টেস্ট তৈরি করা
এখন আমরা @DataJpaTest অ্যানোটেশন ব্যবহার করে UserRepository টেস্ট করব। এখানে আমরা টেস্টের মাধ্যমে User Entity কে ডেটাবেসে সেভ এবং ফাইন্ড করতে যাচ্ছি।
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertEquals;
@DataJpaTest
public class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
public void testSaveAndFindByEmail() {
// Create a new User
User user = new User("John Doe", "john.doe@example.com");
// Save the user
userRepository.save(user);
// Fetch the user from the database
User foundUser = userRepository.findByEmail("john.doe@example.com");
// Verify the user details
assertNotNull(foundUser);
assertEquals("John Doe", foundUser.getName());
assertEquals("john.doe@example.com", foundUser.getEmail());
}
}
এখানে:
@DataJpaTestঅ্যানোটেশন দিয়ে স্প্রিং কন্টেইনারের মধ্যে কেবল JPA সম্পর্কিত বিহেভিয়ার টেস্ট হবে।userRepository.save(user)ব্যবহার করে ডেটাবেসেUserসেভ করা হচ্ছে।userRepository.findByEmail("john.doe@example.com")ব্যবহার করেUserখোঁজা হচ্ছে।
@MockBean এর মাধ্যমে Service Testing
@MockBean অ্যানোটেশন ব্যবহার করে আপনি সার্ভিসের মক বিহেভিয়ার তৈরি করতে পারেন। এটি সাধারণত Service Layer টেস্টিংয়ে ব্যবহৃত হয় যখন আপনি Repository বা External API-এর জন্য প্রকৃত ইনস্ট্যান্স ব্যবহার না করতে চান।
উদাহরণ: @MockBean ব্যবহার করে Service Testing
ধরা যাক, আমাদের একটি UserService ক্লাস রয়েছে, যা UserRepository ব্যবহার করে User ম্যানেজ করে। এখানে আমরা @MockBean ব্যবহার করে UserRepository মক করতে যাচ্ছি।
Step 1: UserService ক্লাস তৈরি করা
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public User getUserByEmail(String email) {
return userRepository.findByEmail(email);
}
}
Step 2: UserServiceTest ক্লাস তৈরি করা
এখন আমরা @MockBean ব্যবহার করে UserService টেস্ট করব। এখানে আমরা UserRepository মক করব, যাতে ডেটাবেসের ইনপুট না দিয়ে UserService ক্লাসটি টেস্ট করা যায়।
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.assertEquals;
@SpringBootTest
public class UserServiceTest {
@Autowired
private UserService userService;
@MockBean
private UserRepository userRepository;
@Test
public void testGetUserByEmail() {
// Create a mock user
User mockUser = new User("John Doe", "john.doe@example.com");
// Mock the repository method
Mockito.when(userRepository.findByEmail("john.doe@example.com")).thenReturn(mockUser);
// Call the service method
User user = userService.getUserByEmail("john.doe@example.com");
// Verify the results
assertEquals("John Doe", user.getName());
assertEquals("john.doe@example.com", user.getEmail());
}
}
এখানে:
- @MockBean ব্যবহার করে
UserRepositoryমক করা হয়েছে, যাতে ডেটাবেসের আসল ইনপুট না দিয়ে আমরাUserServiceটেস্ট করতে পারি। Mockito.when(userRepository.findByEmail("john.doe@example.com")).thenReturn(mockUser)ব্যবহার করে আমরাUserRepositoryএরfindByEmailমেথড মক করেছি।
Conclusion
স্প্রিং বুট জেপিএ (Spring Boot JPA) ব্যবহার করে আপনি @DataJpaTest এবং @MockBean এর মাধ্যমে কার্যকরভাবে টেস্টিং করতে পারেন:
- @DataJpaTest: শুধুমাত্র JPA ডেটাবেস অপারেশন এবং রেপোজিটরি লেয়ারের টেস্টিং এর জন্য ব্যবহৃত হয়।
- @MockBean: সার্ভিস লেয়ার টেস্টিংয়ে ব্যবহৃত হয় যেখানে আপনি মক বিহেভিয়ার তৈরি করে ডিপেনডেন্সি ইনজেকশন করতে পারেন, যেমন UserRepository বা অন্যান্য এক্সটার্নাল সার্ভিসের জন্য।
এভাবে, আপনি সহজেই স্প্রিং বুট জেপিএ অ্যাপ্লিকেশনগুলির টেস্টিং করতে পারেন এবং ডেটাবেস বা বাহ্যিক ডিপেনডেন্সি ছাড়া লজিক টেস্ট করতে পারেন।
Spring Boot JPA Testing হল Spring Boot অ্যাপ্লিকেশনে JPA (Java Persistence API) ভিত্তিক ডেটাবেস অপারেশন পরীক্ষা করার প্রক্রিয়া। Spring Boot JPA Testing সাধারণত JUnit এবং Mockito এর মাধ্যমে করা হয়, যেখানে @DataJpaTest অ্যানোটেশন ব্যবহার করে JPA সম্পর্কিত টেস্ট কেস লেখা হয়। এই টেস্ট কেসগুলিতে ডেটাবেসে ইনসার্ট, আপডেট, ডিলিট, এবং রিড অপারেশন পরীক্ষা করা হয়।
Spring Boot JPA Testing এর মূল বিষয়
- @DataJpaTest: এই অ্যানোটেশনটি Spring Data JPA-র টেস্টিংয়ের জন্য ব্যবহৃত হয়। এটি শুধুমাত্র JPA রিলেটেড টেস্টিং কার্যক্রমকে সক্রিয় করে, যেমন রেপোজিটরি এবং ডেটাবেস সংক্রান্ত টেস্টিং। এই অ্যানোটেশনটি Spring Boot Test এর একটি অংশ এবং JUnit এর সাথে কাজ করে।
- In-Memory Database: টেস্টিংয়ের জন্য সাধারণত ইন-মেমরি ডেটাবেস (যেমন H2, HSQL) ব্যবহার করা হয় যাতে ডেটাবেসের অবস্থা প্রকৃত ডেটাবেসের সাথে মিল না করে এবং টেস্ট শেষে ডেটাবেস ক্লিন করা যায়।
- Repository Testing: Spring Data JPA রেপোজিটরি এবং কুয়েরি মেথডগুলির কার্যকারিতা যাচাই করার জন্য repository layer টেস্ট করা হয়।
- Mocking: Mockito ব্যবহার করে নির্দিষ্ট ডিপেনডেন্সি মক করা যেতে পারে। তবে, JPA-র ক্ষেত্রে @MockBean বা @Autowired দিয়ে সরাসরি রেপোজিটরি ইনজেক্ট করা হয়।
Spring Boot JPA Testing: উদাহরণ
ধরা যাক, আপনার একটি Employee Entity রয়েছে এবং আপনি এটি দিয়ে কিছু ডেটাবেস অপারেশন পরীক্ষা করবেন।
১. Entity Class: Employee
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String position;
// Getters এবং Setters
}
২. Repository Interface: EmployeeRepository
Spring Data JPA-র মাধ্যমে EmployeeRepository ইন্টারফেস তৈরি করা হবে, যেখানে কিছু সাধারণ ডেটাবেস অপারেশন থাকবে:
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
List<Employee> findByPosition(String position);
}
৩. Service Layer: EmployeeService
EmployeeService ক্লাসে রেপোজিটরি ব্যবহার করে কিছু সার্ভিস ফাংশন তৈরি করা হবে:
@Service
public class EmployeeService {
@Autowired
private EmployeeRepository employeeRepository;
public Employee saveEmployee(Employee employee) {
return employeeRepository.save(employee);
}
public List<Employee> getEmployeesByPosition(String position) {
return employeeRepository.findByPosition(position);
}
public void deleteEmployee(Long id) {
employeeRepository.deleteById(id);
}
}
Spring Boot JPA Testing - Test Class
Spring Boot JPA Testing করতে @DataJpaTest অ্যানোটেশন ব্যবহার করা হবে। আমরা রেপোজিটরি এবং সার্ভিস স্তরের কার্যকারিতা যাচাই করার জন্য টেস্ট কেস তৈরি করব।
১. Repository Testing:
@DataJpaTest
public class EmployeeRepositoryTest {
@Autowired
private EmployeeRepository employeeRepository;
@Test
public void testSaveEmployee() {
Employee employee = new Employee();
employee.setName("John Doe");
employee.setPosition("Developer");
Employee savedEmployee = employeeRepository.save(employee);
assertNotNull(savedEmployee);
assertEquals("John Doe", savedEmployee.getName());
}
@Test
public void testFindByPosition() {
Employee employee1 = new Employee();
employee1.setName("John Doe");
employee1.setPosition("Developer");
employeeRepository.save(employee1);
Employee employee2 = new Employee();
employee2.setName("Jane Doe");
employee2.setPosition("Manager");
employeeRepository.save(employee2);
List<Employee> developers = employeeRepository.findByPosition("Developer");
assertEquals(1, developers.size());
assertEquals("John Doe", developers.get(0).getName());
}
@Test
public void testDeleteEmployee() {
Employee employee = new Employee();
employee.setName("John Doe");
employee.setPosition("Developer");
Employee savedEmployee = employeeRepository.save(employee);
employeeRepository.delete(savedEmployee);
Optional<Employee> deletedEmployee = employeeRepository.findById(savedEmployee.getId());
assertFalse(deletedEmployee.isPresent());
}
}
ব্যাখ্যা:
- testSaveEmployee:
Employeeঅবজেক্টটিsave()মেথড ব্যবহার করে ডেটাবেসে সেভ করা হচ্ছে। টেস্টটি যাচাই করে যে সেভ হওয়া অবজেক্টেরnameসঠিকভাবে সেট হয়েছে। - testFindByPosition:
findByPositionমেথডের মাধ্যমে ডেটাবেসেpositionঅনুসারেEmployeeখুঁজে বের করা হচ্ছে। এটি যাচাই করে যেpositionএর মানের সাথে মেলে এমন ডেটা পাওয়া গেছে কিনা। - testDeleteEmployee:
deleteByIdমেথড ব্যবহার করেEmployeeমুছে ফেলা হচ্ছে এবং পরে যাচাই করা হচ্ছে যে ডেটাবেসে ঐEmployeeঅবজেক্টটি আর নেই।
২. Service Layer Testing:
@SpringBootTest
public class EmployeeServiceTest {
@Autowired
private EmployeeService employeeService;
@Autowired
private EmployeeRepository employeeRepository;
@Test
public void testSaveEmployee() {
Employee employee = new Employee();
employee.setName("John Doe");
employee.setPosition("Developer");
Employee savedEmployee = employeeService.saveEmployee(employee);
assertNotNull(savedEmployee);
assertEquals("John Doe", savedEmployee.getName());
}
@Test
public void testGetEmployeesByPosition() {
Employee employee = new Employee();
employee.setName("John Doe");
employee.setPosition("Developer");
employeeRepository.save(employee);
List<Employee> developers = employeeService.getEmployeesByPosition("Developer");
assertEquals(1, developers.size());
assertEquals("John Doe", developers.get(0).getName());
}
@Test
public void testDeleteEmployee() {
Employee employee = new Employee();
employee.setName("John Doe");
employee.setPosition("Developer");
Employee savedEmployee = employeeRepository.save(employee);
employeeService.deleteEmployee(savedEmployee.getId());
Optional<Employee> deletedEmployee = employeeRepository.findById(savedEmployee.getId());
assertFalse(deletedEmployee.isPresent());
}
}
ব্যাখ্যা:
- testSaveEmployee:
EmployeeServiceএরsaveEmployeeমেথডেEmployeeঅবজেক্ট সেভ করা হচ্ছে এবং টেস্টটি যাচাই করছে সেভ করা অবজেক্টেরnameসঠিকভাবে ইনজেক্ট হয়েছে কিনা। - testGetEmployeesByPosition:
EmployeeServiceএরgetEmployeesByPositionমেথডেpositionঅনুসারে ডেটা খুঁজে বের করা হচ্ছে এবং টেস্টটি যাচাই করছে যে সঠিকEmployeeপাওয়া গেছে। - testDeleteEmployee:
EmployeeServiceএরdeleteEmployeeমেথডেEmployeeমুছে ফেলা হচ্ছে এবং পরে যাচাই করা হচ্ছে যে সেইEmployeeআর ডেটাবেসে নেই।
Spring Boot JPA Testing-এ Best Practices
- @DataJpaTest: শুধুমাত্র JPA সম্পর্কিত টেস্টিং করতে এই অ্যানোটেশন ব্যবহার করুন। এটি টেস্ট কনটেক্সটকে দ্রুত তৈরি করতে সাহায্য করে এবং ইন-মেমরি ডেটাবেস ব্যবহার করে টেস্টিং করে।
- Transactional Tests: টেস্টের শেষে ডেটাবেসের অবস্থা সাফ রাখতে @Transactional ব্যবহার করুন, যা টেস্ট শেষে সব পরিবর্তন রোলব্যাক করে।
- In-Memory Databases: টেস্টিংয়ের জন্য H2 বা HSQL এর মতো ইন-মেমরি ডেটাবেস ব্যবহার করুন, যাতে টেস্টের পরে ডেটাবেস পরিষ্কার থাকে।
- Mocking: যখন সার্ভিস স্তরের টেস্ট করছেন, তখন Mockito ব্যবহার করে ডিপেনডেন্সিগুলো মক করতে পারেন।
সারাংশ
Spring Boot JPA Testing হল Spring Boot অ্যাপ্লিকেশনগুলিতে JPA সম্পর্কিত ডেটাবেস অপারেশনগুলির সঠিক কার্যকারিতা যাচাই করার প্রক্রিয়া। @DataJpaTest এবং @SpringBootTest অ্যানোটেশন ব্যবহার করে আমরা রেপোজিটরি এবং সার্ভিস স্তরের টেস্টিং করতে পারি। Spring Boot JPA Testing ডেটাবেসের CRUD অপারেশন, কাস্টম কুয়েরি এবং বিভিন্ন এক্সসেপশন হ্যান্ডলিং পরীক্ষা করতে সহায়তা করে।
Read more